package com.legal.aid.app.config;

import com.legal.aid.app.domain.vo.ChatMessage;
import com.legal.aid.app.mapper.AppCommentMapper;
import com.legal.aid.app.mapper.AppNewsMapper;
import com.legal.aid.app.mapper.ChatMessageMapper;
import com.legal.aid.common.constant.CacheConstants;
import com.legal.aid.common.core.redis.RedisCache;
import com.legal.aid.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Component
public class AppTask {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private AppCommentMapper commentMapper;

    @Autowired
    private AppNewsMapper appNewsMapper;

    @Autowired
    private ChatMessageMapper chatMessageMapper;

    /**
     * 每1分钟同步一次Redis中的点赞数到数据库
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void syncCommentLikeCount() {
        // 获取所有评论点赞的缓存键
        Set<String> keys = (Set<String>) redisCache.keys(CacheConstants.COMMENT_COUNT_PREFIX + "*:*");

        if (keys == null || keys.isEmpty()) {
            return;
        }

        // 分批处理数据
        List<String> keyList = new ArrayList<>(keys);
        int batchSize = 100;
        for (int i = 0; i < keyList.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, keyList.size());
            List<String> batchKeys = keyList.subList(i, endIndex);
            processBatch(batchKeys);
        }
    }

    /**
     * 处理一批数据
     */
    private void processBatch(List<String> keys) {
        List<Long> commentIds = new ArrayList<>();
        List<String> targetTypes = new ArrayList<>();
        List<Integer> likeCounts = new ArrayList<>();

        // 解析Redis key并收集数据
        for (String key : keys) {
            String[] parts = key.split(":");
//   comment:count:caseComment:11
            if (parts.length == 4 && "comment".equals(parts[0]) && "count".equals(parts[1])) {
                try {
//新闻为1，案例为2
                    String targetType = parts[2].equals("newsComment") ? "1" : "2";
                    Long commentId = Long.parseLong(parts[3]);
                    Integer likeCount = redisCache.getCacheObject(key);

                    if (targetType != null && commentId != null && likeCount != null) {
                        commentIds.add(commentId);
                        targetTypes.add(targetType);
                        likeCounts.add(likeCount);
                    }
                } catch (NumberFormatException e) {
                    throw new ServiceException("解析点赞数据失败: " + key);
                }
            }
        }

        // 批量更新数据库
        if (!commentIds.isEmpty()) {
            try {
                commentMapper.batchUpdateCommentLikeCount(commentIds, targetTypes, likeCounts);

                // 删除已处理的Redis缓存
                for (String key : keys) {
                    redisCache.deleteObject(key);
                }
            } catch (Exception e) {
                throw new ServiceException("批量更新点赞数失败: " + e.getMessage());
            }
        }
    }

    /**
     * 热点新闻浏览
     * 定时任务：将Redis中的浏览量同步到数据库
     * 每10分钟执行一次
     */
    @Scheduled(cron = "0 0/10 * * * ?")
    public void syncViewCountToDB() {
        String keyPrefix = CacheConstants.NEWS_VIEW_COUNT_KEY_PREFIX;
        // 获取所有浏览量计数的key
        Set<String> keys = (Set<String>) redisCache.keys(keyPrefix + "*");

        if (keys != null && !keys.isEmpty()) {
            Map<String, Integer> viewCountMap = new HashMap<>();

            // 收集所有需要更新的新闻ID和浏览量
            for (String key : keys) {
                String newsIdStr = key.substring(keyPrefix.length());
                Integer count = redisCache.getCacheObject(key);
                if (count != null && count > 0) {
                    viewCountMap.put(newsIdStr, count);
                }
            }

            // 批量更新数据库
            if (!viewCountMap.isEmpty()) {
                try {
                    appNewsMapper.batchUpdateViewCount(viewCountMap);
                    // 清除已同步的Redis计数
                    for (String key : keys) {
                        redisCache.deleteObject(key);
                    }
                } catch (Exception e) {
                    throw new ServiceException("同步浏览量失败: " + e.getMessage());
                }
            }
        }
    }

    /**
     * 定时任务：每小时检查一次，将未持久化的消息写入数据库
     */
//    @Scheduled(fixedRate = 3600000)
//    public void persistUnpersistedMessages() {
//        // 获取所有会话ID
//        Set<String> historyKeys = (Set<String>) redisCache.keys(CacheConstants.CHAT_HISTORY_KEY + "*");
//
//        for (String historyKey : historyKeys) {
//            // 获取会话中的所有消息ID
//            List<Long> messageIds = redisCache.getCacheList(historyKey);
//
//            for (Long messageId : messageIds) {
//                // 检查消息是否已持久化
//                if (!isMessagePersisted(messageId)) {
//                    // 获取消息内容
//                    ChatMessage message = redisCache.getCacheObject(historyKey + ":msg:" + messageId);
//
//                    if (message != null) {
//                        try {
//                            // 持久化到数据库
//                            chatMessageMapper.insert(message);
//                            // 标记为已持久化
//                            markMessageAsPersisted(messageId);
//                        } catch (Exception e) {
//                            throw new ServiceException("消息持久化失败: " + e.getMessage());
//                        }
//                    }
//                }
//            }
//        }
//    }

//    // 检查消息是否已持久化
//    private boolean isMessagePersisted(Long messageId) {
//        String persistedKey = CacheConstants.PERSISTED_MESSAGES_KEY + messageId;
//        return redisCache.getCacheObject(persistedKey) != null;
//    }
//
//    // 标记消息为已持久化
//    private void markMessageAsPersisted(Long messageId) {
//        String persistedKey = CacheConstants.PERSISTED_MESSAGES_KEY + messageId;
//        redisCache.setCacheObject(persistedKey, "1", 48, TimeUnit.HOURS);
//    }
}
